import operator

from myelin.Ns import XML_SCHEMA as XS
from nodetypes.Ns import SORT_NS, SORT_ASC

#def _order_by_key_num(a):
#    try:
#        return int(a.mOrder_Key[0].rdf_value)
#    except:
#        return -1
#    
#def _order_by_cmp_num(a):
#    try:
#        return int(a.mOrder_Key[0].rdf_value) - int(b.mOrder_key[0].rdf_value)
#    except:
#        return -1
#    
#ORDER_BY_SORT_KEYS = (
#    operator.attrgetter('mModified'),
#    operator.attrgetter('mTag'),
#    operator.attrgetter('dcTitle'),
#    operator.attrgetter('rdfType'),
#    operator.attrgetter('mOrder_Key'),
#    _order_by_key_num,
#    operator.attrgetter('dcCreated')
#)
#
#ORDER_BY_SORT_CMPS = (
#    lambda a,b: cmp(a.mModified, b.mModified),
#    lambda a,b: cmp(a.mTag,b.mTag),
#    lambda a,b: cmp(a.dcTitle,b.dcTitle),
#    lambda a,b: cmp(a.rdfType,b.rdfType),
#    lambda a,b: cmp(a.mOrder_key,b.mOrder_key),
#    _order_by_key_num,
#    lambda a,b: cmp(a.dcCreated,b.dcCreated),
#)

def CreateNumberConv(conv, default=0):
    def f(l):        
        try:
            l = u''.join([l.rdf_value for l in l])
            return l and conv(l) or default
        except:
            return default
    return f

ORDER_CONVERSION = {
    XS + u'string' : lambda l:u''.join([l.rdf_value for l in l]),
    XS + u'integer' : CreateNumberConv(int),
    XS + u'float'  : CreateNumberConv(float,0.0),
}

DEFAULT_ORDER_CONVERSION = ORDER_CONVERSION[XS+u'string']

def OrderByKeys(model, nodes):
    pred = model.mOrder_By
    if not pred:
        return nodes
    
    pred = pred[0].rdf_value
    if not pred:
        return nodes
    
    
    reverse = model.mOrder_Direction
    
    conv = model.mOrder_Type
    conv = conv and ORDER_CONVERSION.get(conv[0].rdf_value) or DEFAULT_ORDER_CONVERSION
    
    #print "ORDER-BY: ", pred, model.rdf_join('mOrder_Direction'), model.rdf_join('mOrder_Type')
        
    nodes.sort(
        reverse=reverse and reverse[0].rdf_value == SORT_ASC or 0,
        key=lambda n: conv(n.rdf_property(pred))
    )
    
    return nodes
          
#def OrderByCmps(model, nodes, key=None):
#    pred = model.mOrder_By
#    if not pred:
#        return nodes
#    
#    pred = pred[0].rdf_value
#    if not pred:
#        return nodes
#    
#    reverse = model.mOrder_Direction
#    reverse = reverse and reverse[0].rdf_value == 'ascending'
#    
#    conv = model.mOrder_Conversion
#    conv = conv and ORDER_CONVERSION.get(conv[0].rdf_value) or ORDER_CONVERSION['string']
#    
#    nodes.sort(
#        reverse=reverse,
#        key=key,
#        cmp=lambda a,b: cmp(conv(a.rdf_property(pred)),conv(a.rdf_property(pred)))
#    )
#    
#    return nodes
    